package com.bleeth.fx.helper;

import cn.hutool.core.util.StrUtil;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseButton;
import javafx.scene.text.Text;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Sakura
 * @version 1.0
 * @date 2021-11-13 22:48
 **/
public class TreeHelper {

    private TreeView<TreeEntity> treeView;

    private Map<String, TreeItem> treeItemMap = new HashMap<>();

    private boolean hasRoot;

    private ContextMenu currentMenu;

    private Map<String, ContextMenu> menuMap = new HashMap<>();


    public static TreeHelper create() {
        TreeHelper treeHelper = new TreeHelper();
        treeHelper.treeView = new TreeView();
        treeHelper.setContextMenu();
        return treeHelper;
    }

    /**
     * 可设置，可不设置，不设置的时候系统自动默认添加root，且不显示
     *
     * @param treeEntity
     * @return
     */
    public TreeHelper setRoot(TreeEntity treeEntity) {
        TreeItem rootItem = new TreeItem(treeEntity);
        treeView.setRoot(rootItem);
        treeItemMap.put(treeEntity.getId(), rootItem);
        treeView.setShowRoot(true);
        hasRoot = true;
        return this;
    }

    /**
     * parentId 为空则加到root下
     *
     * @param parentId
     * @param treeEntity
     * @return
     */
    public TreeHelper addItem(String parentId, TreeEntity treeEntity) {
        if (!hasRoot) {
            TreeEntity rootEntity = TreeEntity.create("root");
            rootEntity.setType(TreeEntity.ROOT_TYPE);
            TreeItem rootItem = new TreeItem(rootEntity);
            treeView.setRoot(rootItem);
            treeView.setShowRoot(false);
            treeItemMap.put(rootEntity.getId(), rootItem);
            hasRoot = true;
        }
        if (StrUtil.isEmpty(parentId) || treeItemMap.get(parentId) == null) {
            TreeItem<TreeEntity> itemEntity = new TreeItem<>(treeEntity);
            treeView.getRoot().getChildren().add(itemEntity);
            treeItemMap.put(treeEntity.getId(), itemEntity);
        } else {
            TreeItem parentItem = treeItemMap.get(parentId);
            TreeItem<TreeEntity> subItem = new TreeItem(treeEntity);
            parentItem.getChildren().add(subItem);
        }
        return this;
    }

    public TreeHelper addContextMenu(String type, ContextMenu menu) {
        menuMap.put(type, menu);
        return this;
    }

    public TreeView build() {
        return treeView;
    }

    public void setContextMenu() {
        treeView.setOnMouseClicked(event -> {
            if (currentMenu != null) {
                currentMenu.hide();
                currentMenu = null;
                return;
            }
            if (!event.getButton().name().equals(MouseButton.SECONDARY.name())) {
                return;
            }
            Node node = event.getPickResult().getIntersectedNode();
            if (node instanceof Text || (node instanceof TreeCell && ((TreeCell) node).getText() != null)) {
                TreeItem<TreeEntity> selectedItem = treeView.getSelectionModel().getSelectedItem();
                if (selectedItem != null) {
                    TreeEntity treeEntity = selectedItem.getValue();
                    String type = treeEntity.getType();
                    if (TreeEntity.DIR_TYPE.equals(type)) {
                        ContextMenu contextMenu = menuMap.get(TreeEntity.DIR_TYPE);
                        if (contextMenu != null) {
                            contextMenu.show(treeView, event.getScreenX(), event.getScreenY());
                            currentMenu = contextMenu;
                        }
                    } else if (TreeEntity.ITEM_TYPE.equals(type)) {
                        ContextMenu contextMenu = menuMap.get(TreeEntity.ITEM_TYPE);
                        if (contextMenu != null) {
                            contextMenu.show(treeView, event.getScreenX(), event.getScreenY());
                            currentMenu = contextMenu;
                        }
                    } else if (TreeEntity.ROOT_TYPE.equals(type)) {
                        ContextMenu contextMenu = menuMap.get(TreeEntity.ROOT_TYPE);
                        if (contextMenu != null) {
                            contextMenu.show(treeView, event.getScreenX(), event.getScreenY());
                            currentMenu = contextMenu;
                        }
                    }
                }
            } else {
                ContextMenu contextMenu = menuMap.get(TreeEntity.ROOT_TYPE);
                if (contextMenu != null) {
                    contextMenu.show(treeView, event.getScreenX(), event.getScreenY());
                    currentMenu = contextMenu;
                }
            }
            if (currentMenu != null) {
                currentMenu.setOnAction(menuEvent -> {
                    currentMenu = null;
                });
            }
        });
    }
}
